// @HEADER
//*********************************************************************//
//  SiYuan: A numerical PDE solver                                     //
//  Copyright (2022) YUAN Xi                                           //
//  This Software is released under the BSD 2-Clause license detailed  //
//  in the file "LICENSE" in the top-level SiYuan directory            //
//*********************************************************************//
// @HEADER

#ifndef __EquationSetFactory_hpp__
#define __EquationSetFactory_hpp__

#include "Panzer_EquationSet_Factory.hpp"
#include "Panzer_EquationSet_Factory_Defines.hpp"
#include "Panzer_CellData.hpp"

#include "DiffusionEquation.hpp"
#include "EquationSet_Magnetostatics.hpp"
#include "MaxwellEquation.hpp"
#include "SchrodingerEquation.hpp"
#include "CahnHilliardEquation.hpp"
#include "ShallowWaterEquation.hpp"
#include "AcousticsEquation.hpp"
#include "GradShafranovEquation.hpp"

namespace SiYuan {

  PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_Diffusion,
					EquationSet_Diffusion)
  PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_Magnetostatics,
					EquationSet_Magnetostatics)
  PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_Schrodinger,
					EquationSet_Schrodinger)
  PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_CahnHilliard,
					EquationSet_CahnHilliard)
  PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_ShallowWater,
					EquationSet_ShallowWater)
  PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_Acoustics,
					EquationSet_Acoustics)
  PANZER_DECLARE_EQSET_TEMPLATE_BUILDER(EquationSet_GradShafranov,
					EquationSet_GradShafranov)

  class EquationSetFactory : public panzer::EquationSetFactory {

  public:

    Teuchos::RCP<panzer::EquationSet_TemplateManager<panzer::Traits> >
    buildEquationSet(const Teuchos::RCP<Teuchos::ParameterList>& params,
		     const int& default_integration_order,
		     const panzer::CellData& cell_data,
		     const Teuchos::RCP<panzer::GlobalData>& global_data,
		     const bool build_transient_support) const
    {
      Teuchos::RCP<panzer::EquationSet_TemplateManager<panzer::Traits> > eq_set= 
	      Teuchos::rcp(new panzer::EquationSet_TemplateManager<panzer::Traits>);
      
      bool found = false;
      
      PANZER_BUILD_EQSET_OBJECTS("Heat", EquationSet_Diffusion)
      PANZER_BUILD_EQSET_OBJECTS("MagnetoStatics", EquationSet_Magnetostatics)
      PANZER_BUILD_EQSET_OBJECTS("Schrodinger", EquationSet_Schrodinger)
      PANZER_BUILD_EQSET_OBJECTS("CahnHilliard", EquationSet_CahnHilliard)
      PANZER_BUILD_EQSET_OBJECTS("ShallowWater", EquationSet_ShallowWater)
      PANZER_BUILD_EQSET_OBJECTS("Acoustics", EquationSet_Acoustics)
      PANZER_BUILD_EQSET_OBJECTS("GradShafranov", EquationSet_GradShafranov)
      
      if (!found) {
	std::string msg = "Error - the \"Equation Set\" with \"Type\" = \"" + params->get<std::string>("Type") +
	  "\" is not a valid equation set identifier. Please supply the correct factory.\n";
	TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, msg);
      }
      
      return eq_set;
    }
    
  };

}

#endif
